#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>

using namespace std;


namespace bit
{
	template<class T>
	class shared_ptr
	{
	public:
		shared_ptr(T* ptr)
			:_ptr(ptr)
			,_count(new int(1))
		{}

		shared_ptr(const shared_ptr<T>& sp)
			:_ptr(sp._ptr)
			, _count(sp._count)
		{
			++(*_count);
		}

		T& operator*()
		{
			return *_ptr;
		}

		T* operator->()
		{
			return _ptr;
		}

		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			if (_ptr == sp._ptr)
				return *this;

			if (--(*_count)  == 0)
			{
				delete _ptr;
				delete _count;
			}

			_ptr = sp._ptr;
			_count = sp._count;
			++(*_count);
		
			return *this;
		}

		T* get() const
		{
			return _ptr;
		}

		~shared_ptr()
		{
			if (--(*_count) == 0)
			{
				cout << "shared_ptr" << endl;
				delete _ptr;
				delete _count;
			}
		}


	private:
		T* _ptr;
		int* _count;
	};

	template<class T>
	class weak_ptr
	{
	public:
		weak_ptr() 
			:_ptr(nullptr)
		{}
		weak_ptr(const shared_ptr<T>& sp)
			:_ptr(sp.get())
		{}

		weak_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			_ptr = sp.get();
			return *this;
		}

		T& operator*()
		{
			return *_ptr;
		}

		T* operator->()
		{
			return _ptr;
		}

		~weak_ptr()
		{
			cout << "weak_ptr" << endl;
		}
	private:
		T* _ptr;
	};
}

struct A
{
	int val;
	bit::weak_ptr<A> next;
	bit::weak_ptr<A> prev;

	~A()
	{
		cout << "AAA" << endl;
	}
};
int main()
{
	bit::shared_ptr<A> n1(new A);
	bit::shared_ptr<A> n2(new A);

	n1->next = n2;
	n2->prev = n1;

	return 0;
}